package org.openspml.providers.one_c.commands;

import org.openspml.message.ExtendedRequest;
import org.openspml.message.SpmlResponse;
import org.openspml.providers.one_c.api.connection.GlobalContext;
import org.openspml.providers.one_c.api.users.InfoBaseUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author <A href="mailto:abashev at gmail dot com">Alexey Abashev</A>
 * @version $Id$
 */
public class ExtendedRequestCommand {
	private static final String CHANGE_USER_PASSWORD = "changeUserPassword";
	private static final String RESET_USER_PASSWORD = "resetUserPassword";
	
	private static final String ACCOUNT_ID_ATTR = "accountId";
	private static final String PASSWORD_ATTR = "accountId";
	
	private final Logger log = LoggerFactory.getLogger(ExtendedRequestCommand.class);

	public SpmlResponse execute(GlobalContext context, ExtendedRequest request) {
		final String operation = request.getOperationIdentifier().getId();
		
		SpmlResponse response;
		
		if (operation.equals(CHANGE_USER_PASSWORD)) {
			String accountId = (String) request.getAttribute(ACCOUNT_ID_ATTR).getValue();
			String newPassword =  (String) request.getAttribute(PASSWORD_ATTR).getValue();
			
			log.info("Changing password for user [{}]", accountId);

			response = request.createResponse();
			
			try {
				if (changePassword(context, accountId, newPassword)) {
					response.setResult(SpmlResponse.RESULT_SUCCESS);
				} else {
					response.setError(SpmlResponse.ERROR_NO_SUCH_IDENTIFIER);
					response.setErrorMessage("Unable to find user with id [" + accountId + "]");
				}
			} catch (Exception e) {
				response.setError(SpmlResponse.ERROR_CUSTOM_ERROR);
				response.setErrorMessage(e);
			}
		} else if (operation.equals(RESET_USER_PASSWORD)) {
			String accountId = (String) request.getAttribute(ACCOUNT_ID_ATTR).getValue();

			log.info("Reset password for user [{}]", accountId);

			response = request.createResponse();

			try {
				if (resetPassword(context, accountId)) {
					response.setResult(SpmlResponse.RESULT_SUCCESS);
				} else {
					response.setError(SpmlResponse.ERROR_NO_SUCH_IDENTIFIER);
					response.setErrorMessage("Unable to find user with id [" + accountId + "]");
				}
			} catch (Exception e) {
				response.setError(SpmlResponse.ERROR_CUSTOM_ERROR);
				response.setErrorMessage(e);
			}
		} else {
			// Unsupported feature
			response = request.createResponse();
			
			response.setError(SpmlResponse.ERROR_UNSUPPORTED_OPERATION);
			response.setErrorMessage(
					"Operation '" + operation + "' not supported for extended requests"
			);
		}
		
		return response;
	}
	
	/**
	 * 
	 * @param context
	 * @param accountId
	 * @param newPassword
	 * @return true - if operation was successful, false - if not
	 */
	protected boolean changePassword(
			GlobalContext context, String accountId, String newPassword
	) {
		InfoBaseUser user = context.getInfoBaseUsers().findByName(accountId);
		
		if (user != null) {
			user.setPassword(newPassword);
			
			return true;
		}
		
		return false;
	}
	
	/**
	 * 
	 * @param context
	 * @param accountId
	 * @return true - if operation was successful, false - if not
	 */
	protected boolean resetPassword(GlobalContext context, String accountId) {
		InfoBaseUser user = context.getInfoBaseUsers().findByName(accountId);
		
		if (user != null) {
			user.setPassword("");
			
			return true;
		}
		
		return false;
	}
}
